home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / dev / src / expat-src.lha / expat-1.95.2 / xmlwf / xmlmime.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-28  |  2.8 KB  |  162 lines

  1. #include <string.h>
  2. #include "xmlmime.h"
  3.  
  4. static
  5. const char *getTok(const char **pp)
  6. {
  7.   /* inComment means one level of nesting; inComment+1 means two levels etc */
  8.   enum { inAtom, inString, init, inComment };
  9.   int state = init;
  10.   const char *tokStart = 0;
  11.   for (;;) {
  12.     switch (**pp) {
  13.     case '\0':
  14.       if (state == inAtom)
  15.     return tokStart;
  16.       return 0;
  17.     case ' ':
  18.     case '\r':
  19.     case '\t':
  20.     case '\n':
  21.       if (state == inAtom)
  22.     return tokStart;
  23.       break;
  24.     case '(':
  25.       if (state == inAtom)
  26.     return tokStart;
  27.       if (state != inString)
  28.     state++;
  29.       break;
  30.     case ')':
  31.       if (state > init)
  32.     --state;
  33.       else if (state != inString)
  34.     return 0;
  35.       break;
  36.     case ';':
  37.     case '/':
  38.     case '=':
  39.       if (state == inAtom)
  40.     return tokStart;
  41.       if (state == init)
  42.     return (*pp)++;
  43.       break;
  44.     case '\\':
  45.       ++*pp;
  46.       if (**pp == '\0')
  47.     return 0;
  48.       break;
  49.     case '"':
  50.       switch (state) {
  51.       case inString:
  52.     ++*pp;
  53.     return tokStart;
  54.       case inAtom:
  55.     return tokStart;
  56.       case init:
  57.     tokStart = *pp;
  58.     state = inString;
  59.     break;
  60.       }
  61.       break;
  62.     default:
  63.       if (state == init) {
  64.     tokStart = *pp;
  65.     state = inAtom;
  66.       }
  67.       break;
  68.     }
  69.     ++*pp;
  70.   }
  71.   /* not reached */
  72. }
  73.  
  74. /* key must be lowercase ASCII */
  75.  
  76. static
  77. int matchkey(const char *start, const char *end, const char *key)
  78. {
  79.   if (!start)
  80.     return 0;
  81.   for (; start != end; start++, key++)
  82.     if (*start != *key && *start != 'A' + (*key - 'a'))
  83.       return 0;
  84.   return *key == '\0';
  85. }
  86.  
  87. void getXMLCharset(const char *buf, char *charset)
  88. {
  89.   const char *next, *p;
  90.  
  91.   charset[0] = '\0';
  92.   next = buf;
  93.   p = getTok(&next);
  94.   if (matchkey(p, next, "text"))
  95.     strcpy(charset, "us-ascii");
  96.   else if (!matchkey(p, next, "application"))
  97.     return;
  98.   p = getTok(&next);
  99.   if (!p || *p != '/')
  100.     return;
  101.   p = getTok(&next);
  102. #if 0
  103.   if (!matchkey(p, next, "xml") && charset[0] == '\0')
  104.     return;
  105. #endif
  106.   p = getTok(&next);
  107.   while (p) {
  108.     if (*p == ';') {
  109.       p = getTok(&next);
  110.       if (matchkey(p, next, "charset")) {
  111.     p = getTok(&next);
  112.     if (p && *p == '=') {
  113.       p = getTok(&next);
  114.       if (p) {
  115.         char *s = charset;
  116.         if (*p == '"') {
  117.           while (++p != next - 1) {
  118.         if (*p == '\\')
  119.           ++p;
  120.         if (s == charset + CHARSET_MAX - 1) {
  121.           charset[0] = '\0';
  122.           break;
  123.         }
  124.         *s++ = *p;
  125.           }
  126.           *s++ = '\0';
  127.         }
  128.         else {
  129.           if (next - p > CHARSET_MAX - 1)
  130.         break;
  131.           while (p != next)
  132.         *s++ = *p++;
  133.           *s = 0;
  134.           break;
  135.         }
  136.       }
  137.     }
  138.     break;
  139.       }
  140.     }
  141.   else
  142.     p = getTok(&next);
  143.   }
  144. }
  145.  
  146. #ifdef TEST
  147.  
  148. #include <stdio.h>
  149.  
  150. int main(int argc, char **argv)
  151. {
  152.   char buf[CHARSET_MAX];
  153.   if (argc <= 1)
  154.     return 1;
  155.   printf("%s\n", argv[1]);
  156.   getXMLCharset(argv[1], buf);
  157.   printf("charset=\"%s\"\n", buf);
  158.   return 0;
  159. }
  160.  
  161. #endif /* TEST */
  162.